package momo.multitree.simulation.result;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

public class ScaledAvgStdDev {

	public ScaledAvgStdDev() {
	}
	
	public void getResult(String input, String output) {
		String csvFormat = this.toCSVFormat(input);
		this.writeToFile(output, csvFormat);
	}
	
	private String toCSVFormat(String filename) {
		StringBuffer buffer = new StringBuffer();
		Map<String, Double[]> val = getData(filename);
		
		double[] latCost = new double[100];
		double[] latStab = new double[100];
		double[] costLat = new double[100];
		double[] costStab = new double[100];
		double[] stabLat = new double[100];
		double[] stabCost = new double[100];
		double[] algoLat = new double[100];;
		double[] algoCost = new double[100];
		double[] algoStab = new double[100];
		double[] score = new double[100];
		
		int pos = 0;
		for ( String key : val.keySet() ) {
			
			Double[] d = val.get(key);
			
			latCost[pos] = d[0];
			latStab[pos] = d[1];
			costLat[pos] = d[2];
			costStab[pos] = d[3];
			stabLat[pos] = d[4];
			stabCost[pos] = d[5];
			algoLat[pos] = d[6];
			algoCost[pos] = d[7];
			algoStab[pos] = d[8];
			score[pos] = d[9];
			pos = ++pos % 100;
			
			if ( pos == 0 ) {
				buffer.append( 	mean(score) + "," +
								stdDev(score) + "," +
								mean(latCost) + "," +
								stdDev(latCost) + "," +
								mean(latStab) + "," +
								stdDev(latStab) + "," +
								mean(costLat) + "," +
								stdDev(costLat) + "," +
								mean(costStab) + "," +
								stdDev(costStab) + "," +
								mean(stabLat) + "," +
								stdDev(stabLat) + "," +
								mean(stabCost) + "," +
								stdDev(stabCost) + "," +
								mean(algoLat) + "," +
								stdDev(algoLat) + "," +
								mean(algoCost) + "," +
								stdDev(algoCost) + "," +
								mean(algoStab) + "," +
								stdDev(algoStab) + "\n" );
			}
		}
		
		return buffer.toString();
	}
	
	private void writeToFile(String filename, String result) {
		try {
			BufferedWriter out = new BufferedWriter(new FileWriter(filename));
			out.write(result);
			out.flush();
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private double mean(double[] values) {
		double sum = 0d;
		for ( double v : values )
			sum += v;
		return sum / values.length;
	}
	
	private double stdDev(double[] values) {
		double mean = mean(values);
		double sum = 0;
		for ( double v : values )
			sum += Math.pow((v-mean), 2);
		return Math.sqrt( sum / (values.length-1) );
	}
	
	private Map<String, Double[]> getData(String filename) {
		Map<String, Double[]> val = new LinkedHashMap<String, Double[]>();
		try {
			BufferedReader in = new BufferedReader(new FileReader(new File(filename)));
			String line = "";
			while ( ( line=in.readLine() ) != null ) {
				String tokens[] = line.split(",");
				String key = tokens[0];
				Double[] values = { Double.valueOf(tokens[11]), 
									Double.valueOf(tokens[12]),
									Double.valueOf(tokens[13]),
									Double.valueOf(tokens[15]),
									Double.valueOf(tokens[16]),
									Double.valueOf(tokens[17]),
									Double.valueOf(tokens[19]),
									Double.valueOf(tokens[20]),
									Double.valueOf(tokens[21]),
									Double.valueOf(tokens[22])
									};
				val.put(key, values);
			}
		}catch (FileNotFoundException e) {
			e.printStackTrace();
		}catch (IOException ioe) {
			ioe.printStackTrace();
		}
		return val;
	}
	
	public static void main(String args[]) {
		ScaledAvgStdDev app = new ScaledAvgStdDev();
		String input = "fw_08_relative_performance.csv";
		String output = "fw_08_avg_std_dev.csv";
		app.getResult(input, output);
	}
	
}//end of class ScaledAvgStdDev
